package framework.view.components.graphics
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.Sprite;
import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.net.URLRequest;
import flash.system.LoaderContext;

import framework.view.components.IComponent;

import mx.utils.UIDUtil;

import utils.Tracer;
import utils.URLUtil;

/**
 * Asset
 * @author Jay
 * 
 */
public class Asset extends Sprite implements IComponent
{
	//==========================================================================
	//  Constructor
	//==========================================================================
	public function Asset()
	{
		super();
	}
	//==========================================================================
	//  Variables
	//==========================================================================
	public var id:String = UIDUtil.createUID();
	
	protected var _url:String;
	
	protected var loader:Loader;
	
	protected var _content:DisplayObject;
	
	public function get content():DisplayObject
	{
		return _content;
	}
	
	asset_ns function set content(value:DisplayObject):void
	{
		if (_content && this.contains(_content))
		{
			this.removeChild(_content);
		}
		_content = value;
		
		try
		{
			this.addChild(content);
		}
		catch (error:Error)
		{
			throw new IllegalOperationError("**" + _url + "**" + error.message);
		}
		
		forceUpdate();
		_isLoaded = true;
	}
	
	protected var _onComplete:Function;
	
	public function get onComplete():Function
	{
		return _onComplete;
	}
	
	public function set onComplete(value:Function):void
	{
		_onComplete = value;
	}
	
	private var _onError:Function;
	
	public function get onError():Function
	{
		return _onError;
	}
	
	public function set onError(value:Function):void
	{
		_onError = value;
	}
	
	protected var _isLoaded:Boolean = false;
	
	public function get isLoaded():Boolean
	{
		return _isLoaded;
	}
	
	protected var w:Number = -1;
	
	override public function set width(value:Number):void
	{
		w = value;
		if (isLoaded)
		{
			super.width = w;
		}
	}
	
	override public function get width():Number
	{
		if (isLoaded)
		{
			if (w == -1) return super.width;
		}
		return w;
	}
	
	protected var h:Number = -1;
	
	override public function set height(value:Number):void
	{
		h = value;
		if (isLoaded)
		{
			super.height = h;
		}
	}
	
	override public function get height():Number
	{
		if (isLoaded)
		{
			if (h == -1) return super.height;
		}
		return h;
	}
	//==========================================================================
	//  Public methods
	//==========================================================================
	public function set url(value:String):void
	{
		_url = value;
	}
	
	public function get url():String
	{
		return _url;
	}
	
	public function load():void
	{
		if(loader)
		{
			clearEventListener();
			try
			{
				loader.close();
			}
			catch (error:Error)
			{
					
			}
		}
		loader = new Loader();
		setupEventListener();
		loader.load( URLUtil.getRequest(url));
	}
	
	public function commitProperty():void
	{
		
	}
	
	public function dispose():void
	{
		if (loader)
		{
			clearEventListener();
			try
			{
				loader.close();
			}
			catch (error:Error)
			{
				//do nothing
			}
		}
		onComplete = null;
		onError = null;
	}
	
	protected function forceUpdate():void
	{
		//*/
		// Force DisplayObject update dimensions
		var bmpData:BitmapData = new BitmapData(1, 1);
		bmpData.draw(this);
		//*/
	}
	
	protected function setupEventListener():void
	{
		if(loader && !loader.contentLoaderInfo.hasEventListener(Event.COMPLETE))
		{
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedHandler);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
		}
	}
	
	protected function clearEventListener():void
	{
		if(loader && loader.contentLoaderInfo.hasEventListener(Event.COMPLETE))
		{
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadedHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
		}
	}
	
	protected function loadedHandler(event:Event):void
	{
		clearEventListener();  
		asset_ns::content = loader.content;
		forceUpdate();
		_isLoaded = true;
		if (w != -1 && h != -1)
		{
			super.width = w;
			super.height = h;
		}
		if (onComplete != null) onComplete(this);
		onComplete = null;
		onError = null;
	}
	
	protected function errorHandler(event:Event):void
	{
		clearEventListener();
		if (onError != null) onError(this);
		onComplete = null;
		onError = null;
	}
}
}







